#include <iostream>
#include <fstream>
using namespace std;
class Student {
public:
    const string name="";
    int age;
    Student() {};
    const char* get_name()const{
        return name.c_str();
    }

    void info() {
        cout << "Age:" << age << " Name: " << &name << endl;
    }
};
void read_student(string filename) {
    ifstream f_handle(filename, ios::in | ios::binary);
    Student s;
    if (!f_handle)
        cout << "Error" << endl;
    while (f_handle.read((char *) &s, sizeof(s))) {
        int readedBytes = f_handle.gcount();
        cout << "Readed " << readedBytes << " Bytes\n";
        s.info();
    }
    f_handle.close();
}
int main()
{
    Student s;
    string filename = "/home/liushuai/cxxcode/code/stream/ex19/student.dat";
    fstream ioFile(filename, ios::in|ios::out|ios::binary);//用既读又写的方式打开
    if(!ioFile) {
        cout << "error" ;
        return 0;
    }
    ioFile.seekg(0,ios::end); //定位读指针到文件尾部，
    //以便用以后tellg 获取文件长度
    int L = 0,R; // L是折半查找范围内第一个记录的序号
    // R是折半查找范围内最后一个记录的序号
    R = ioFile.tellg() / sizeof(Student) - 1;
    //首次查找范围的最后一个记录的序号就是: 记录总数- 1
    do {
        int mid = (L + R)/2; //要用查找范围正中的记录和待查找的名字比对
        ioFile.seekg(mid *sizeof(Student),ios::beg); //定位到正中的记录
        ioFile.read((char *)&s, sizeof(s));
        int tmp = s.name.compare("Jack");
        if(tmp == 0) { //找到了
            s.age = 25;
            ioFile.seekp(mid*sizeof(Student),ios::beg);
            ioFile.write((char*)&s, sizeof(s));
            break;
        }
        else if (tmp > 0) //继续到前一半查找
            R = mid - 1 ;
        else  //继续到后一半查找
            L = mid + 1;
    }while(L <= R);
    ioFile.close();
    read_student(filename);
    return 0;
}
